package com.xaicode.template.gendata.mall.common;

import com.xaicode.template.gendata.common.ParamUtil;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author Locker xaicode@sina.com
 * @version 1.0
 * @date 2022/5/24 0024 22:07
 */
@Data
@NoArgsConstructor
public class RandomOptionGroup<T> {

    int totalWeight = 0;
    List<RanOpt> optList = new ArrayList<>();

    public RandomOptionGroup(int totalWeight, List<RanOpt> optList) {
        this.totalWeight = totalWeight;
        this.optList = optList;
    }

    public static class Builder<T> {
        List<RanOpt> optList = new ArrayList<>();
        int totalWeight = 0;

        public Builder add(T value, int weight) {
            RanOpt<T> ranOpt;
            int i;
            for (ranOpt = new RanOpt<>(value, weight), this.totalWeight += weight, i = 0; i < weight; ) {
                this.optList.add(ranOpt);
                i++;
            }
            return this;
        }

        public RandomOptionGroup<T> build() {
            return new RandomOptionGroup<>(this.totalWeight, this.optList);
        }

        public Builder<T> totalWeight(int totalWeight) {
            this.totalWeight = totalWeight;
            return this;
        }

        public Builder<T> optList(List<RanOpt> optList) {
            this.optList = optList;
            return this;
        }

        public String toString() {
            return "RandomOptionGroup.Builder(totalWeight=" + this.totalWeight + ", optList=" + this.optList + ")";
        }
    }

    public static <T> Builder<T> builder() {
        return new Builder<>();
    }

    public RandomOptionGroup(String... values) {
        for (String value : values) {
            this.totalWeight++;
            this.optList.add(new RanOpt<>(value, 1));
        }
    }

    public RandomOptionGroup(RanOpt<T>... opts) {
        for (RanOpt<T> opt : opts) {
            this.totalWeight += opt.getWeight();
            for (int i = 0; i < opt.getWeight(); i++) {
                this.optList.add(opt);
            }
        }
    }

    public RandomOptionGroup(int trueWeight, int falseWeight) {
        this((RanOpt<T>[]) new RanOpt[]{new RanOpt<>(Boolean.valueOf(true), trueWeight), new RanOpt<>(Boolean.valueOf(false), falseWeight)});
    }

    public RandomOptionGroup(String trueRate) {
        this(ParamUtil.checkRatioNum(trueRate).intValue(), 100 - ParamUtil.checkRatioNum(trueRate).intValue());
    }

    public T getValue() {
        int i = (new Random()).nextInt(this.totalWeight);
        return ((RanOpt<T>) this.optList.get(i)).getValue();
    }

    public RanOpt<T> getRandomOpt() {
        int i = (new Random()).nextInt(this.totalWeight);
        return this.optList.get(i);
    }

    public String getRandStringValue() {
        int i = (new Random()).nextInt(this.totalWeight);
        return ((RanOpt<String>) this.optList.get(i)).getValue();
    }

    public Integer getRandIntValue() {
        int i = (new Random()).nextInt(this.totalWeight);
        return ((RanOpt<Integer>) this.optList.get(i)).getValue();
    }


    public Boolean getRandBoolValue() {
        int i = (new Random()).nextInt(this.totalWeight);
        return ((RanOpt<Boolean>) this.optList.get(i)).getValue();
    }

    public static void main(String[] args) {
        RanOpt[] opts = {new RanOpt<>("zhang3", 20), new RanOpt<>("li4", 30), new RanOpt<>("wang5", 50)};
        RandomOptionGroup randomOptionGroup = new RandomOptionGroup((RanOpt<?>[]) opts);
        for (int i = 0; i < 10; i++)
            System.out.println(randomOptionGroup.getRandomOpt().getValue());
    }
}
